package com.xbongbong.pro.statistic.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.elasticsearch.pojo.StatisticBiFormDataEntity;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.enums.BiRelTableEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.statistic.pojo.SlaveSourcePojo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 多表处理
 * @author zhouwq
 * @date 2020/10/20 14:34
 */

@Component
public class BiSubFormDataMultiHandle extends AbstractBiSubFormDataHelp{

    @Override
    public void handleSubFormData(List esList, ChartEntity chartEntity, PageHelper pageHelper, JSONArray tableHead, BoolQueryBuilder boolQueryBuilder, SearchRequest searchRequest) throws XbbException, IllegalAccessException {
        JSONObject driverSourcesObject = chartEntity.getDriverSources();
        SlaveSourcePojo driverSourcePojo = JSON.toJavaObject(driverSourcesObject, SlaveSourcePojo.class);
        //从数据表，多表数据源
        BiRelTableEnum biRelTableEnum = customHelp.getBiRelTableEnum(driverSourcePojo.getBusinessType(), driverSourcePojo.getSaasMark());
        String type = biRelTableEnum.getType();
        SearchRequest searchSubFormRequest = new SearchRequest(searchRequest.indices());
        PageRequest pageSubFormRequest = subFormSearchQueryBuild(type, chartEntity.getCorpid(), pageHelper, boolQueryBuilder, searchSubFormRequest);
        XbbAggregatedPage<StatisticBiFormDataEntity> statisticBiFormDataList = xbbElasticsearchRestTemplate.queryForPages(pageSubFormRequest, searchSubFormRequest, StatisticBiFormDataEntity.class);
        Map<String, List<String>> subFormAttrList = subFormAttrListGet(tableHead);
        //parentID 父esId -> （attr 字段名 -> 对应字段的子表单集合）
        Map<String, Map<String, List<StatisticBiFormDataEntity>>> parentIdToList = new HashMap<>(1 << 4);
        for (StatisticBiFormDataEntity entity : statisticBiFormDataList.getContent()) {
            String parentId = entity.getParent();
            Map<String, List<StatisticBiFormDataEntity>> attrToList = new HashMap<>(1 << 4);
            List<StatisticBiFormDataEntity> entities = new ArrayList<>();
            entities.add(entity);
            attrToList.put(entity.getAttr(), entities);
            parentIdToList.merge(parentId, attrToList, (oldest, latest) -> {
                List<StatisticBiFormDataEntity> list = new ArrayList<>();
                list.add(entity);
                oldest.merge(entity.getAttr(), list, (v1, v2) -> {
                    v1.addAll(v2);
                    return v1;
                });
                return oldest;
            });
        }
        for (Object obj : esList) {
            StatisticBiFormDataEntity e = (StatisticBiFormDataEntity) obj;
            String esId = e.getEsId();
            //attr 字段名 -> 对应字段的子表单集合
            Map<String, List<StatisticBiFormDataEntity>> attrToList = parentIdToList.get(esId);
            if (attrToList == null) {
                continue;
            }
            for (Map.Entry<String, List<String>> entry : subFormAttrList.entrySet()) {
                String key = entry.getKey();
                List<StatisticBiFormDataEntity> list = attrToList.get(key);
                if (list == null || list.size() == 0) {
                    continue;
                }
                JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(list));
                Class userCla = e.getClass();
                Field[] fs = userCla.getDeclaredFields();
                for (Field f : fs) {
                    if (Objects.equals(key, f.getName())) {
                        f.setAccessible(true);
                        f.set(e, jsonArray);
                    }
                }
            }
        }
    }
}
